home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 365_01 / curses.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  23KB  |  1,025 lines

  1. /* curses.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    14407 SW Teal Blvd. #C
  6.  *    Beaverton, OR 97005
  7.  *    kirkenda@cs.pdx.edu
  8.  */
  9.  
  10.  
  11. /* This file contains the functions & variables needed for a tiny subset of
  12.  * curses.  The principle advantage of this version of curses is its
  13.  * extreme speed.  Disadvantages are potentially larger code, few supported
  14.  * functions, limited compatibility with full curses, and only stdscr.
  15.  */
  16.  
  17. #include "config.h"
  18. #include "vi.h"
  19.  
  20. #if ANY_UNIX
  21. # if UNIXV
  22. #  ifdef TERMIOS
  23. #   include    <termios.h>
  24. #  else
  25. #   include    <termio.h>
  26. #  endif
  27. #  ifdef S5WINSIZE
  28. #   include    <sys/stream.h>    /* winsize struct defined in one of these? */
  29. #   include    <sys/ptem.h>
  30. #  else
  31. #   undef    TIOCGWINSZ    /* we can't handle it correctly yet */
  32. #  endif
  33. # else
  34. #  include    <sgtty.h>
  35. # endif
  36. #endif
  37.  
  38. #if TOS
  39. # include    <osbind.h>
  40. #endif
  41.  
  42. #if OSK
  43. # include    <sgstat.h>
  44. #endif
  45.  
  46. #if VMS
  47. extern int VMS_read_raw;  /* Set in initscr() */
  48. #endif
  49.  
  50.  
  51. extern char    *getenv();
  52. static void     starttcap();
  53.  
  54. /* variables, publicly available & used in the macros */
  55. char    *termtype;    /* name of terminal entry */
  56. short    ospeed;        /* speed of the tty, eg B2400 */
  57. #if OSK
  58. char    PC_;    /* Pad char */
  59. char    *BC;    /* backspace character string */
  60. #else
  61. char    PC;        /* Pad char */
  62. #endif
  63. WINDOW    *stdscr;    /* pointer into kbuf[] */
  64. WINDOW    kbuf[KBSIZ];    /* a very large output buffer */
  65. int    LINES;        /* :li#: number of rows */
  66. int    COLS;        /* :co#: number of columns */
  67. int    AM;        /* :am:  boolean: auto margins? */
  68. int    PT;        /* :pt:  boolean: physical tabs? */
  69. char    *VB;        /* :vb=: visible bell */
  70. char    *UP;        /* :up=: move cursor up */
  71. char    *SO = "";    /* :so=: standout start */
  72. char    *SE = "";    /* :se=: standout end */
  73. char    *US = "";    /* :us=: underline start */
  74. char    *UE = "";    /* :ue=: underline end */
  75. char    *MD = "";    /* :md=: bold start */
  76. char    *ME = "";    /* :me=: bold end */
  77. char    *AS = "";    /* :as=: alternate (italic) start */
  78. char    *AE = "";    /* :ae=: alternate (italic) end */
  79. #ifndef NO_VISIBLE
  80. char    *MV;        /* :mv=: "visible" selection start */
  81. #endif
  82. char    *CM;        /* :cm=: cursor movement */
  83. char    *CE;        /* :ce=: clear to end of line */
  84. char    *CD;        /* :cd=: clear to end of screen */
  85. char    *AL;        /* :al=: add a line */
  86. char    *DL;        /* :dl=: delete a line */
  87. #if OSK
  88. char    *SR_;        /* :sr=: scroll reverse */
  89. #else
  90. char    *SR;        /* :sr=: scroll reverse */
  91. #endif
  92. char    *KS = "";    /* :ks=: init string for cursor */
  93. char    *KE = "";    /* :ke=: restore string for cursor */
  94. char    *KU;        /* :ku=: key sequence sent by up arrow */
  95. char    *KD;        /* :kd=: key sequence sent by down arrow */
  96. char    *KL;        /* :kl=: key sequence sent by left arrow */
  97. char    *KR;        /* :kr=: key sequence sent by right arrow */
  98. char    *HM;        /* :HM=: key sequence sent by the <Home> key */
  99. char    *EN;        /* :EN=: key sequence sent by the <End> key */
  100. char    *PU;        /* :PU=: key sequence sent by the <PgUp> key */
  101. char    *PD;        /* :PD=: key sequence sent by the <PgDn> key */
  102. char    *KI;        /* :kI=: key sequence sent by the <Insert> key */
  103. #ifndef NO_FKEY
  104. char    *FKEY[NFKEYS];    /* :k0=: ... :k9=: sequences sent by function keys */
  105. #endif
  106. char    *IM = "";    /* :im=: insert mode start */
  107. char    *IC = "";    /* :ic=: insert the following character */
  108. char    *EI = "";    /* :ei=: insert mode end */
  109. char    *DC;        /* :dc=: delete a character */
  110. char    *TI = "";    /* :ti=: terminal init */    /* GB */
  111. char    *TE = "";    /* :te=: terminal exit */    /* GB */
  112. #ifndef NO_CURSORSHAPE
  113. #if 1
  114. char    *CQ = (char *)0;/* :cQ=: normal cursor */
  115. char    *CX = (char *)1;/* :cX=: cursor used for EX command/entry */
  116. char    *CV = (char *)2;/* :cV=: cursor used for VI command mode */
  117. char    *CI = (char *)3;/* :cI=: cursor used for VI input mode */
  118. char    *CR = (char *)4;/* :cR=: cursor used for VI replace mode */
  119. #else
  120. char    *CQ = "";    /* :cQ=: normal cursor */
  121. char    *CX = "";    /* :cX=: cursor used for EX command/entry */
  122. char    *CV = "";    /* :cV=: cursor used for VI command mode */
  123. char    *CI = "";    /* :cI=: cursor used for VI input mode */
  124. char    *CR = "";    /* :cR=: cursor used for VI replace mode */
  125. #endif
  126. #endif
  127. char    *aend = "";    /* end an attribute -- either UE or ME */
  128. char    ERASEKEY;    /* backspace key taken from ioctl structure */
  129. #ifndef NO_COLOR
  130. char    normalcolor[16];
  131. char    SOcolor[16];
  132. char    SEcolor[16];
  133. char    UScolor[16];
  134. char    UEcolor[16];
  135. char    MDcolor[16];
  136. char    MEcolor[16];
  137. char    AScolor[16];
  138. char    AEcolor[16];
  139. # ifndef NO_POPUP
  140. char    POPUPcolor[16];
  141. # endif
  142. # ifndef NO_VISIBLE
  143. char    VISIBLEcolor[16];
  144. # endif
  145. #endif
  146.  
  147. #if ANY_UNIX
  148. # if UNIXV
  149. #  ifdef TERMIOS
  150. static struct termios    oldtermio;    /* original tty mode */
  151. static struct termios    newtermio;    /* cbreak/noecho tty mode */
  152. #  else
  153. static struct termio    oldtermio;    /* original tty mode */
  154. static struct termio    newtermio;    /* cbreak/noecho tty mode */
  155. #  endif
  156. # else
  157. static struct sgttyb    oldsgttyb;    /* original tty mode */
  158. static struct sgttyb    newsgttyb;    /* cbreak/nl/noecho tty mode */
  159. static int        oldint;        /* ^C or DEL, the "intr" character */
  160. #  ifdef TIOCSLTC
  161. static int        oldswitch;    /* ^Z, the "suspend" character */
  162. static int        olddswitch;    /* ^Y, the "delayed suspend" char */
  163. static int        oldquote;    /* ^V, the "quote next char" char */
  164. #  endif
  165. # endif
  166. #endif
  167.  
  168. #if OSK
  169. static struct sgbuf    oldsgttyb;    /* orginal tty mode */
  170. static struct sgbuf    newsgttyb;    /* noecho tty mode */
  171. #endif
  172.  
  173. static char    *capbuf;    /* capability string buffer */
  174.  
  175.  
  176. /* Initialize the Curses package. */
  177. void initscr()
  178. {
  179.     /* make sure TERM variable is set */
  180.     termtype = getenv("TERM");
  181.  
  182. #if VMS
  183.     /* VMS getenv() handles TERM as a environment setting.  Foreign 
  184.      * terminal support can be implemented by setting the ELVIS_TERM
  185.      * logical or symbol to match a tinytcap entry.
  186.      */
  187.     if (!strcmp(termtype,"unknown"))
  188.         termtype = getenv("ELVIS_TERM");
  189. #endif
  190. #if MSDOS
  191.     /* For MS-DOS, if TERM is unset we can default to "pcbios", or
  192.      * maybe "rainbow".
  193.      */
  194.     if (!termtype)
  195.     {
  196. #ifdef RAINBOW
  197.         if (*(unsigned char far*)(0xffff000eL) == 6   /* Rainbow 100a */
  198.          || *(unsigned char far*)(0xffff000eL) == 148)/* Rainbow 100b */
  199.         {
  200.             termtype = "rainbow";
  201.         }
  202.         else
  203. #endif
  204.             termtype = "pcbios";
  205.     }
  206.     if (!strcmp(termtype, "pcbios"))
  207. #else
  208.     if (!termtype)
  209. #endif
  210.     {
  211. #if ANY_UNIX
  212.         write(2, "Environment variable TERM must be set\n", (unsigned)38);
  213.         exit(1);
  214. #endif
  215. #if OSK
  216.         writeln(2, "Environment variable TERM must be set\n", (unsigned)38);
  217.         exit(1);
  218. #endif
  219. #if AMIGA
  220.         termtype = TERMTYPE;
  221.         starttcap(termtype);
  222. #endif
  223. #if MSDOS
  224.         starttcap("pcbios");
  225. #endif
  226. #if TOS
  227.         termtype = "vt52";
  228.         starttcap(termtype);
  229. #endif
  230. #if VMS
  231.         write(2, "UNKNOWN terminal: define ELVIS_TERM\n", (unsigned)36);
  232.         exit(1);
  233. #endif
  234.     }
  235.     else
  236.     {
  237. #if MSDOS
  238.         *o_pcbios = 0;
  239. #endif
  240.         /* start termcap stuff */
  241.         starttcap(termtype);
  242.     }
  243.  
  244.     /* create stdscr and curscr */
  245.     stdscr = kbuf;
  246.  
  247.     /* change the terminal mode to cbreak/noecho */
  248. #if ANY_UNIX
  249. # if UNIXV
  250. #  ifdef TERMIOS
  251.     tcgetattr(2, &oldtermio);
  252. #  else
  253.     ioctl(2, TCGETA, &oldtermio);
  254. #  endif
  255. # else
  256.     ioctl(2, TIOCGETP, &oldsgttyb);
  257. # endif
  258. #endif
  259.  
  260. #if OSK
  261.     _gs_opt(0, &oldsgttyb);
  262. #endif
  263.  
  264. #if VMS
  265.     VMS_read_raw = 1;   /* cbreak/noecho */
  266.     vms_open_tty();
  267. #endif
  268.     resume_curses(TRUE);
  269. }
  270.  
  271. /* Shut down the Curses package. */
  272. void endwin()
  273. {
  274.     /* change the terminal mode back the way it was */
  275.     suspend_curses();
  276. #if AMIGA
  277.     amiclosewin();
  278. #endif
  279. }
  280.  
  281.  
  282. static int curses_active = FALSE;
  283.  
  284. /* Send any required termination strings.  Turn off "raw" mode. */
  285. void suspend_curses()
  286. {
  287. #if ANY_UNIX && !UNIXV
  288.     struct tchars    tbuf;
  289. # ifdef TIOCSLTC
  290.     struct ltchars    ltbuf;
  291. # endif
  292. #endif
  293. #ifndef NO_CURSORSHAPE
  294.     if (has_CQ)
  295.     {
  296.         do_CQ();
  297.     }
  298. #endif
  299.     if (has_TE)                    /* GB */
  300.     {
  301.         do_TE();
  302.     }
  303.     if (has_KE)
  304.     {
  305.         do_KE();
  306.     }
  307. #ifndef NO_COLOR
  308.     quitcolor();
  309. #endif
  310.     refresh();
  311.  
  312.     /* change the terminal mode back the way it was */
  313. #if ANY_UNIX
  314. # if UNIXV
  315. #  if TERMIOS
  316.     tcsetattr(2, TCSADRAIN, &oldtermio);
  317. #  else
  318.     ioctl(2, TCSETAW, &oldtermio);
  319. #  endif
  320. # else
  321.     ioctl(2, TIOCSETP, &oldsgttyb);
  322.  
  323.     ioctl(2, TIOCGETC, (struct sgttyb *) &tbuf);
  324.     tbuf.t_intrc = oldint;
  325.     ioctl(2, TIOCSETC,